home *** CD-ROM | disk | FTP | other *** search
/ Apple WWDC 1996 / WWDC96_1996 (CD).toast / Technology Materials / MacApp Release 10 / MacApp Release 10 - HD Ready / Libraries / App / Sources / UApplication.cp < prev    next >
Encoding:
Text File  |  1996-04-03  |  68.0 KB  |  2,348 lines  |  [TEXT/MPS ]

  1. //----------------------------------------------------------------------------------------
  2. // UApplication.cp 
  3. // Copyright © 1984-96 by Apple Computer, Inc. All rights reserved.
  4. //----------------------------------------------------------------------------------------
  5.  
  6. #ifndef __UAPPLICATION__
  7. #include "UApplication.h"
  8. #endif
  9.  
  10. // MacApp
  11.  
  12. #ifndef __UBEHAVIOR__
  13. #include "UBehavior.h"
  14. #endif
  15.  
  16. #ifndef __UBUSYCURSOR__
  17. #include "UBusyCursor.h"
  18. #endif
  19.  
  20. #ifndef __UCLIPBOARDMGR__
  21. #include "UClipboardMgr.h"
  22. #endif
  23.  
  24. #if qContainer
  25.     #ifndef __UCONTAINER__
  26.     #include "UContainer.h"
  27.     #endif
  28. #endif
  29.  
  30. #ifndef __UDEBUG__
  31. #include "UDebug.h"
  32. #endif
  33.  
  34. #if qDebug
  35.     #ifndef __UDEBUGVIEW__
  36.     #include "UDebugView.h"
  37.     #endif
  38. #endif
  39.  
  40. #ifndef __UDEPENDENCIES__
  41. #include "UDependencies.h"
  42. #endif
  43.  
  44. #ifndef __UDESIGNATOR__
  45. #include "UDesignator.h"
  46. #endif
  47.  
  48. #ifndef __UDOCUMENT__
  49. #include "UDocument.h"
  50. #endif
  51.  
  52. #ifndef __UERRORMGR__
  53. #include "UErrorMgr.h"
  54. #endif
  55.  
  56. #ifndef __UFILE__
  57. #include "UFile.h"
  58. #endif
  59.  
  60. #ifndef __FLOATWINDOW__
  61. #include "FloatWindow.h"
  62. #endif
  63.  
  64. #ifndef __UGEOMETRY__
  65. #include "UGeometry.h"
  66. #endif
  67.  
  68. #ifndef __UMACAPPGLOBALS__
  69. #include "UMacAppGlobals.h"
  70. #endif
  71.  
  72. #ifndef __UMACAPPUTILITIES__
  73. #include "UMacAppUtilities.h"
  74. #endif
  75.  
  76. #if qPowerTalk
  77.     #ifndef __UMAILABLE__
  78.     #include "UMailable.h"
  79.     #endif
  80. #endif
  81.  
  82. #ifndef __UMEMORY__
  83. #include "UMemory.h"
  84. #endif
  85.  
  86. #ifndef __UMENUMGR__
  87. #include "UMenuMgr.h"
  88. #endif
  89.  
  90. #ifndef __UPATCH__
  91. #include "UPatch.h"
  92. #endif
  93.  
  94. #ifndef __UPERFORM__
  95. #include "UPerform.h"
  96. #endif
  97.  
  98. #ifndef __UPRINTHANDLER__
  99. #include "UPrintHandler.h"
  100. #endif
  101.  
  102. #ifndef __UOSASCRIPT__
  103. #include "UOSAScript.h"
  104. #endif
  105.  
  106. #ifndef __USCRIPTING__
  107. #include "UScripting.h"
  108. #endif
  109.  
  110. #ifndef __USECTIONMGR__
  111. #include "USectionMgr.h"
  112. #endif
  113.  
  114. #ifndef __USEGMENTS__
  115. #include "USegments.h"
  116. #endif
  117.  
  118. #ifndef __USTREAM__
  119. #include "UStream.h"
  120. #endif
  121.  
  122. #ifndef __UTABBEHAVIORS__
  123. #include "UTabBehaviors.h"
  124. #endif
  125.  
  126. #ifndef __UVIEWSERVER__
  127. #include "UViewServer.h"
  128. #endif
  129.  
  130. #if qNeedsVU
  131.     #ifndef __UVUASSIST__
  132.     #include "UVUAssist.h"
  133.     #endif
  134. #endif
  135.  
  136. #ifndef __UWINDOW__
  137. #include "UWindow.h"
  138. #endif
  139.  
  140. // CALib
  141.  
  142. #if qContainer
  143.     #ifndef _CALIB_
  144.     #include "CALib.h"
  145.     #endif
  146. #endif
  147.  
  148. // Toolbox
  149.  
  150. #ifndef __AEREGISTRY__
  151. #include <AERegistry.h>
  152. #endif
  153.  
  154. #ifndef __DEVICES__
  155. #include <Devices.h>
  156. #endif
  157.  
  158. #ifndef __DISKINIT__
  159. #include <DiskInit.h>
  160. #endif
  161.  
  162. #ifndef __ERRORS__
  163. #include <Errors.h>
  164. #endif
  165.  
  166. #ifndef __LOWMEM__
  167. #include <LowMem.h>
  168. #endif
  169.  
  170. #ifndef __RESOURCES__
  171. #include <Resources.h>
  172. #endif
  173.  
  174. #ifndef __TOOLUTILS__
  175. #include <ToolUtils.h>
  176. #endif
  177.  
  178. // ANSI
  179.  
  180. #ifndef __STDIO__
  181. #include <stdio.h>
  182. #endif
  183.  
  184. // Other
  185.  
  186. #if defined(__MWERKS__) && (qDebug || qTheDebugger)
  187.     #ifndef __CWDEBUG__
  188.         #include "CWDebug.h"
  189.     #endif    
  190. #endif
  191.  
  192. //----------------------------------------------------------------------------------------
  193. // Constant definitions
  194. //----------------------------------------------------------------------------------------
  195.  
  196. enum SystemJustification { smSysJustLeft = 0, smSysJustRight = -1 };
  197.     // Constants to use with GetSysDirection() and SetSysDirection().
  198.  
  199.  
  200. //----------------------------------------------------------------------------------------
  201. // Global variable definitions.
  202. //----------------------------------------------------------------------------------------
  203.  
  204. TApplication* gApplication;
  205. //Boolean gInitialized;
  206. //AEAddressDesc gServerAddress;
  207.  
  208.  
  209. Boolean hadCreditsStringList;        // does the rsrc 'STR#' == kDefaultCredits exist ?
  210. short lastCreditsStringIndex;        // the last CString in the STR# to be displayed
  211. long lastCreditsShownTicks;            // the tickcount when the last Credit was Shown
  212. CStringHandle originalText;            // the about box's original text (prior to credits)
  213. short waitTicks;                    // how long to wait between credits 
  214.  
  215. //========================================================================================
  216. // GLOBAL Procedures
  217. //========================================================================================
  218. static pascal Boolean DoShowAboutAppFilter(DialogRef theDialog,
  219.                                            EventRecord& theEvent,
  220.                                            short& itemHit);
  221. static void DoSetupTheMenus(void* yourDataPtr);
  222.  
  223. static WindowRef GetWindowToClose();
  224.  
  225. #undef Inherited
  226.  
  227. //----------------------------------------------------------------------------------------
  228. // DoShowAboutAppFilter: 
  229. //----------------------------------------------------------------------------------------
  230. #pragma segment MAAboutApp
  231.  
  232. pascal Boolean DoShowAboutAppFilter(DialogRef theDialog,
  233.                                     EventRecord& theEvent,
  234.                                     short& itemHit)
  235. {
  236.     CStr255 s;
  237.     CStr255 originalStr;
  238.     Handle item;
  239.     Boolean returnValue = FALSE;
  240.     short itemType;
  241.     CRect box;
  242.  
  243.     switch (theEvent.what)
  244.     {
  245.         case keyDown:
  246.             switch ((unsigned char)(((theEvent.message) & charCodeMask)))
  247.             {
  248.                 case chEnter:
  249.                 case chReturn:
  250.                     DoAlertKeyDown(theDialog, ok);
  251.                     break;
  252.             }
  253.             break;
  254.  
  255.         case nullEvent:
  256.             if ((TickCount() - lastCreditsShownTicks) > waitTicks)
  257.             {
  258.                 short itemNo = 1;
  259.  
  260.                 do
  261.                 {
  262.                     item = NULL;
  263.                     GetDialogItem(theDialog, itemNo, &itemType, &item, box);
  264.                     if (((itemType) & 0x7F) == statText)// we don't care if its enabled or not 
  265.                         break;
  266.                     else
  267.                         ++itemNo;
  268.                 } while (item);
  269.  
  270.                 GetIndString(s, kDefaultCredits, lastCreditsStringIndex);
  271.  
  272.                 if (!s.IsEmpty())
  273.                 {
  274.                     // save the original text 
  275.                     if ((lastCreditsStringIndex == 1) && ((*originalText)->IsEmpty() && item))
  276.                     {
  277.                         GetDialogItemText(item, originalStr);
  278.                         SetString((StringHandle)originalText, (ConstStr255Param)&originalStr);
  279.                     }
  280.                     ++lastCreditsStringIndex;
  281.                     lastCreditsShownTicks = TickCount();
  282.                     if (item)
  283.                         SetDialogItemText(item, s);
  284.                     waitTicks = (short)Min((s.Length() * 6), 60);
  285.                 }
  286.                 else                            // no more items 
  287.                     {
  288.                         lastCreditsStringIndex = 1;
  289.                         lastCreditsShownTicks = TickCount();
  290.                         if (item)
  291.                         {
  292.                             originalStr = **originalText;
  293.                             SetDialogItemText(item, originalStr);
  294.                         }
  295.                         waitTicks = 6 * 60;
  296.                     }
  297.             }
  298.             break;
  299.     } // switch
  300.  
  301.     // Forward on to the standard filter 
  302.     if (gMacAppAlertFilter)
  303.         returnValue = ((ModalFilterProcPtr)gMacAppAlertFilter)(theDialog, &theEvent, &itemHit);
  304.  
  305.     return returnValue;
  306. } // DoShowAboutAppFilter 
  307.  
  308. //========================================================================================
  309. // CLASS TQuitCommand
  310. //========================================================================================
  311. #undef Inherited
  312. #define Inherited TCommand
  313.  
  314. #pragma segment MAApplicationRes
  315. MA_DEFINE_CLASS_M1(TQuitCommand, Inherited);
  316.  
  317. //----------------------------------------------------------------------------------------
  318. // TQuitCommand: Empty constructor to satisfy the compiler.
  319. //----------------------------------------------------------------------------------------
  320. #pragma segment ConstructorRes
  321.  
  322. TQuitCommand::TQuitCommand()
  323.     : fRespondingToAE(FALSE),
  324.       fInProcessP(NULL),
  325.       fMessage(NULL),
  326.       fReply(NULL)
  327. {
  328. } // TQuitCommand::TQuitCommand
  329.  
  330. //----------------------------------------------------------------------------------------
  331. // TQuitCommand destructor
  332. //----------------------------------------------------------------------------------------
  333. #pragma segment MADestructorRes
  334.  
  335. TQuitCommand::~TQuitCommand()
  336. {
  337.     if (fInProcessP != NULL)
  338.         *fInProcessP = FALSE;
  339. }
  340.  
  341. //----------------------------------------------------------------------------------------
  342. // TQuitCommand::IQuitCommand: 
  343. //----------------------------------------------------------------------------------------
  344. #pragma segment MASelCommand
  345.  
  346. void TQuitCommand::IQuitCommand(CommandNumber itsCommandNumber, Boolean* statusP)
  347. {
  348.     this->ICommand(itsCommandNumber, gApplication, kCantUndo,
  349.                    kDoesNotCauseChange, NULL);
  350.     
  351.     fPriority++;        // Lower our priority.
  352.     fInProcessP = statusP;
  353.     if (fInProcessP != NULL)
  354.         *fInProcessP = TRUE;
  355.  
  356. //----------------------------------------------------------------------------------------
  357. // TQuitCommand::IQuitCommand: 
  358. //----------------------------------------------------------------------------------------
  359. #pragma segment MASelCommand
  360.  
  361. void TQuitCommand::IQuitCommand(TAppleEvent* message ,
  362.                                 TAppleEvent* reply,
  363.                                 Boolean* statusP)
  364. {
  365.     this->ICommand(cQuit, gApplication, kCantUndo,
  366.                    kDoesNotCauseChange, NULL);
  367.  
  368.     fMessage = message;
  369.     fReply = reply;
  370.     fPriority++;        // Lower our priority.
  371.     fInProcessP = statusP;
  372.     if (fInProcessP != NULL)
  373.         *fInProcessP = TRUE;
  374.  
  375.     fRespondingToAE = TRUE;
  376.  
  377. //----------------------------------------------------------------------------------------
  378. // TQuitCommand::IsReadyToExecute: 
  379. //----------------------------------------------------------------------------------------
  380. #pragma segment MAApplicationRes
  381.  
  382. Boolean TQuitCommand::IsReadyToExecute()    // Override
  383. {
  384.     // Don't execute Quit if application has a dialog posed modally!
  385.     if (gApplication->InModalState())
  386.         return FALSE;
  387.     else
  388.         return fReadyToExecute;
  389. }
  390.  
  391. //----------------------------------------------------------------------------------------
  392. // TQuitCommand::DoIt: 
  393. //----------------------------------------------------------------------------------------
  394. #pragma segment MAApplicationRes
  395.  
  396. void TQuitCommand::DoIt()
  397. {
  398.     FailInfo fi;
  399.     Try(fi)
  400.     {
  401.         // Close all windows and documents in window order then close
  402.         // all documentless windows.  Finally, shut down the application.
  403.         DoCloseInWindowOrder();
  404.         DoCloseWindowlessDocuments();
  405.         DoCloseApplication();
  406.         
  407.         fi.Success();
  408.     }
  409.     else
  410.     {
  411.         if (fRespondingToAE)
  412.             fi.ReSignal();
  413.         else if (fi.error != userCanceledErr)
  414.             gApplication->ShowError(fi.error, 0);
  415.     }
  416. } // TQuitCommand::DoIt 
  417.  
  418. //----------------------------------------------------------------------------------------
  419. // GetWindowToClose: 
  420. //----------------------------------------------------------------------------------------
  421. #pragma segment MAUtilitiesRes
  422.  
  423. WindowRef GetWindowToClose()
  424. {
  425.     WindowRef currentWindow = (WindowRef)LMGetWindowList();
  426.     Boolean found = FALSE;
  427.     while (currentWindow && !found)
  428.     {
  429.         if (currentWindow != gWorkPort)
  430.         {
  431.             TWindow* aWindow = gApplication->WMgrToWindow(currentWindow);
  432.             if (aWindow)
  433.                 found = aWindow->fFreeOnClosing || aWindow->IsShown();
  434.             else
  435.                 found = TRUE;
  436.         }
  437.         if (!found)
  438.             currentWindow = GetNextWindow(currentWindow);
  439.     }
  440.     return currentWindow;
  441. }
  442.  
  443. //----------------------------------------------------------------------------------------
  444. // TQuitCommand::DoCloseInWindowOrder: 
  445. //----------------------------------------------------------------------------------------
  446. #pragma segment MAApplicationRes
  447.  
  448. void TQuitCommand::DoCloseInWindowOrder()
  449. {
  450.     // This will iterate through all open windows and will close the associated
  451.     // document if there is one or will close the window if there is no document.
  452.     // (Ghost documents are not closed here.  But their windows are.)
  453.     WindowRef aWindowPtr;
  454.     while ((aWindowPtr = GetWindowToClose()) != NULL)
  455.     {
  456.         TWindow* aWindow = gApplication->WMgrToWindow(aWindowPtr);
  457.         if (aWindow)
  458.         {
  459.             TDocument* windowsDocument = aWindow->fDocument;
  460.             if (windowsDocument != NULL && !windowsDocument->GetIsGhostDocument())
  461.                 CloseADocument(windowsDocument);
  462.             else
  463.                 CloseAWindow(aWindow);
  464.         }
  465.         else
  466.             gApplication->CloseToolboxWindow(aWindowPtr);
  467.     }
  468.  
  469. //----------------------------------------------------------------------------------------
  470. // TQuitCommand::DoCloseWindowlessDocuments: 
  471. //----------------------------------------------------------------------------------------
  472. #pragma segment MAApplicationRes
  473.  
  474. void TQuitCommand::DoCloseWindowlessDocuments()
  475. {
  476.     // This really doesn't care if the document is windowless or not, it's
  477.     // just that all documents with windows should have been closed by now.
  478.     CNoGhostDocsIterator iter(gApplication);
  479.     
  480.     for (TDocument* aDocument = iter.FirstDocument();
  481.              iter.More(); aDocument = iter.NextDocument())
  482.     {
  483.         // Closing the document will close any associated windows.
  484.         MAVolatileInit(TCloseDocCommand*, aCloseCommand, NULL);
  485.         MAVolatileInit(Boolean, oldTempAlloc, TemporaryAllocation(TRUE));
  486.         MAVolatileInit(Boolean, oldObjectPerm, AllocateObjectsFromPerm(FALSE));
  487.     
  488.         FailInfo fi;
  489.         Try(fi)
  490.         {
  491.             aCloseCommand = aDocument->MakeCloseCommand();
  492.             if (fRespondingToAE)
  493.                 aCloseCommand->fUseAppleEvent = FALSE;
  494.             aCloseCommand->Process();
  495.  
  496.             TemporaryAllocation(oldTempAlloc);
  497.             AllocateObjectsFromPerm(oldObjectPerm);
  498.     
  499.             fi.Success();
  500.         }
  501.         else                                // Recover
  502.         {
  503.             TemporaryAllocation(oldTempAlloc);
  504.             AllocateObjectsFromPerm(oldObjectPerm);
  505.             fi.ReSignal();
  506.         }
  507.     }
  508. }
  509.  
  510. //----------------------------------------------------------------------------------------
  511. // TQuitCommand::CloseAWindow: 
  512. //----------------------------------------------------------------------------------------
  513. #pragma segment MAApplicationRes
  514.  
  515. void TQuitCommand::CloseAWindow(TWindow* aWindow)
  516. {
  517.     Boolean record = !fRespondingToAE
  518.                      && (gClipboardMgr->fClipWindow != aWindow)
  519.                      && aWindow->IsShown();
  520.     MAVolatileInit(TCloseWindowCommand*, aCloseWindowCommand, NULL);
  521.     MAVolatileInit(Boolean, oldTempAlloc, TemporaryAllocation(TRUE));
  522.     MAVolatileInit(Boolean, oldObjectPerm, AllocateObjectsFromPerm(FALSE));
  523.  
  524.     FailInfo fi;
  525.     Try(fi)
  526.     {
  527.         aCloseWindowCommand = new TCloseWindowCommand;
  528.         aCloseWindowCommand->ICloseWindowCommand(cClose, aWindow);
  529.         if (!record)
  530.             aCloseWindowCommand->fUseAppleEvent = FALSE;
  531.         aCloseWindowCommand->Process();
  532.  
  533.         TemporaryAllocation(oldTempAlloc);
  534.         AllocateObjectsFromPerm(oldObjectPerm);
  535.  
  536.         fi.Success();
  537.     }
  538.     else                                // Recover
  539.     {
  540.         TemporaryAllocation(oldTempAlloc);
  541.         AllocateObjectsFromPerm(oldObjectPerm);
  542.  
  543.         fi.ReSignal();
  544.     }
  545.  
  546. //----------------------------------------------------------------------------------------
  547. // TQuitCommand::DoCloseDocuments: 
  548. //----------------------------------------------------------------------------------------
  549. #pragma segment MAApplicationRes
  550.  
  551. void TQuitCommand::CloseADocument(TDocument* aDocument)
  552. {
  553.     // Closing the document will close any associated windows.
  554.     MAVolatileInit(TCloseDocCommand*, aCloseCommand, NULL);
  555.     MAVolatileInit(Boolean, oldTempAlloc, TemporaryAllocation(TRUE));
  556.     MAVolatileInit(Boolean, oldObjectPerm, AllocateObjectsFromPerm(FALSE));
  557.  
  558.     FailInfo fi;
  559.     Try(fi)
  560.     {
  561.         aCloseCommand = aDocument->MakeCloseCommand();
  562.         if (fRespondingToAE)
  563.             aCloseCommand->fUseAppleEvent = FALSE;
  564.         aCloseCommand->Process();
  565.  
  566.         TemporaryAllocation(oldTempAlloc);
  567.         AllocateObjectsFromPerm(oldObjectPerm);
  568.  
  569.         fi.Success();
  570.     }
  571.     else                                // Recover
  572.     {
  573.         TemporaryAllocation(oldTempAlloc);
  574.         AllocateObjectsFromPerm(oldObjectPerm);
  575.  
  576.         fi.ReSignal();
  577.     }
  578. }
  579.  
  580. //----------------------------------------------------------------------------------------
  581. // TQuitCommand::DoCloseApplication: 
  582. //----------------------------------------------------------------------------------------
  583. #pragma segment MAApplicationRes
  584.  
  585. void TQuitCommand::DoCloseApplication()
  586. {
  587.     // Final Stage: We're ready to do the final shutdown now that 
  588.     // all windows and documents have been closed.
  589.     Boolean oldTempAlloc = TemporaryAllocation(TRUE);
  590.     Boolean oldObjectPerm = AllocateObjectsFromPerm(FALSE);
  591.     
  592.     TQuitAppCommand* aQuitAppCommand = new TQuitAppCommand;
  593.     aQuitAppCommand->IQuitAppCommand(cQuit);
  594.     if (fRespondingToAE)
  595.         aQuitAppCommand->fUseAppleEvent = FALSE;
  596.     aQuitAppCommand->Process();
  597.     
  598.     TemporaryAllocation(oldTempAlloc);
  599.     AllocateObjectsFromPerm(oldObjectPerm);
  600. }
  601.  
  602. //========================================================================================
  603. // CLASS TQuitAppCommand
  604. //========================================================================================
  605. #undef Inherited
  606. #define Inherited TCommand
  607.  
  608. #pragma segment MAApplicationRes
  609. MA_DEFINE_CLASS_M1(TQuitAppCommand, Inherited);
  610.  
  611. //----------------------------------------------------------------------------------------
  612. // TQuitAppCommand constructor
  613. //----------------------------------------------------------------------------------------
  614. #pragma segment ConstructorRes
  615.  
  616. TQuitAppCommand::TQuitAppCommand()
  617. {
  618. } // TQuitAppCommand::TQuitAppCommand
  619.  
  620. //----------------------------------------------------------------------------------------
  621. // TQuitAppCommand destructor
  622. //----------------------------------------------------------------------------------------
  623. #pragma segment MADestructorRes
  624.  
  625. TQuitAppCommand::~TQuitAppCommand()
  626. {
  627. }
  628.  
  629. //----------------------------------------------------------------------------------------
  630. // TQuitAppCommand::IQuitAppCommand: 
  631. //----------------------------------------------------------------------------------------
  632. #pragma segment MASelCommand
  633.  
  634. void TQuitAppCommand::IQuitAppCommand(CommandNumber itsCommandNumber)
  635. {
  636.     this->ICommand(itsCommandNumber, gApplication, kCantUndo, kDoesNotCauseChange, NULL);
  637.  
  638. //----------------------------------------------------------------------------------------
  639. // TQuitAppCommand::MakeAppleEvent: 
  640. //----------------------------------------------------------------------------------------
  641. #pragma segment MAApplicationRes
  642.  
  643. TAppleEvent* TQuitAppCommand::MakeAppleEvent()
  644. {
  645.     MAVolatileInit(TAppleEvent*, mayFailEvent, NULL);
  646.  
  647.     FailInfo fi;
  648.     Try(fi)
  649.     {
  650.         CAEDesc mySpecifier;
  651.         TAppleEvent*    theEvent = new TAppleEvent;
  652.         theEvent->IAppleEvent(kCoreEventClass, kAEQuitApplication, gServerAddress, kAEWaitReply);
  653.         mayFailEvent = theEvent;
  654.         gApplication->MakeObjectSpecifier(mySpecifier, formName);
  655.         theEvent->WriteParameter(keyDirectObject, mySpecifier);
  656.         fi.Success();
  657.     }
  658.     else // Recover
  659.     {
  660.         mayFailEvent = (TAppleEvent*)FreeIfObject(mayFailEvent);
  661.         fi.ReSignal();
  662.     }
  663.     
  664.     return mayFailEvent;
  665. }    
  666.  
  667. //----------------------------------------------------------------------------------------
  668. // TQuitAppCommand::IsReadyToExecute: 
  669. //----------------------------------------------------------------------------------------
  670. #pragma segment MAApplicationRes
  671.  
  672. Boolean TQuitAppCommand::IsReadyToExecute()    // Override
  673. {
  674.     // Don't execute Quit if application has a dialog posed modally!
  675.     if (gApplication->InModalState())
  676.         return FALSE;
  677.     else
  678.         return fReadyToExecute;
  679. }
  680.  
  681. //----------------------------------------------------------------------------------------
  682. // TQuitAppCommand::DoIt: 
  683. //----------------------------------------------------------------------------------------
  684. #pragma segment MAApplicationRes
  685.  
  686. void TQuitAppCommand::DoIt()
  687. {
  688.     FailInfo fi;
  689.     Try(fi)
  690.     {
  691.         gApplication->fDone = TRUE;
  692.         gApplication->Close();
  693.         fi.Success();
  694.     }
  695.     else // Recover
  696.     {
  697.         gApplication->fDone = FALSE;
  698.         fi.ReSignal();
  699.     }
  700. } // TQuitAppCommand::DoIt 
  701.  
  702. //========================================================================================
  703. // CLASS TNewDocumentCommand
  704. //========================================================================================
  705. #undef Inherited
  706. #define Inherited TCommand
  707.  
  708. #pragma segment MAOpen
  709. MA_DEFINE_CLASS_M1(TNewDocumentCommand, Inherited);
  710.  
  711. //----------------------------------------------------------------------------------------
  712. // TNewDocumentCommand: Empty constructor to satisfy the compiler.
  713. //----------------------------------------------------------------------------------------
  714. #pragma segment ConstructorRes
  715.  
  716. TNewDocumentCommand::TNewDocumentCommand()
  717. {
  718. } // TNewDocumentCommand::TNewDocumentCommand
  719.  
  720. //----------------------------------------------------------------------------------------
  721. // TNewDocumentCommand destructor
  722. //----------------------------------------------------------------------------------------
  723. #pragma segment MADestructorRes
  724.  
  725. TNewDocumentCommand::~TNewDocumentCommand()
  726. {
  727. }
  728.  
  729. //----------------------------------------------------------------------------------------
  730. // TNewDocumentCommand::DoIt: 
  731. //----------------------------------------------------------------------------------------
  732. #pragma segment MAOpen
  733.  
  734. void TNewDocumentCommand::DoIt()
  735. {
  736.     gApplication->OpenNew(fIdentifier);
  737. } // TNewDocumentCommand::DoIt 
  738.  
  739. //----------------------------------------------------------------------------------------
  740. // TNewDocumentCommand::INewDocumentCommand: 
  741. //----------------------------------------------------------------------------------------
  742. #pragma segment MASelCommand
  743.  
  744. void TNewDocumentCommand::INewDocumentCommand(CommandNumber itsCommandNumber)
  745. {
  746.     this->ICommand(itsCommandNumber, gApplication, kCantUndo, kDoesNotCauseChange, NULL);
  747. } // TNewDocumentCommand::INewDocumentCommand 
  748.  
  749. //----------------------------------------------------------------------------------------
  750. // TNewDocumentCommand::MakeAppleEvent: 
  751. //----------------------------------------------------------------------------------------
  752. #pragma segment MACommandRes
  753.  
  754. TAppleEvent* TNewDocumentCommand::MakeAppleEvent()
  755. {
  756.     // Create a recordable apple event
  757.     TAppleEvent * theEvent = NULL;
  758.     CTempDesc theAppDesc;
  759.  
  760.     gApplication->MakeObjectSpecifier(theAppDesc);
  761.     
  762.     theEvent = TAppleEvent::MakeCreateElementEvent(gServerAddress, kAEWaitReply,
  763.         theAppDesc, cDocument, kAEBeginning, CAEDesc::fgNullDesc, CAEDesc::fgNullDesc);
  764.     return theEvent;
  765. }
  766.  
  767. //========================================================================================
  768. // CLASS TFilesCommand
  769. //========================================================================================
  770. #undef Inherited
  771. #define Inherited TServerCommand
  772.  
  773. #pragma segment MASelCommand
  774. MA_DEFINE_CLASS_M1(TFilesCommand, Inherited);
  775.  
  776. //----------------------------------------------------------------------------------------
  777. // TFilesCommand constructor
  778. //----------------------------------------------------------------------------------------
  779. #pragma segment MASelCommand
  780.  
  781. TFilesCommand::TFilesCommand()
  782. {
  783.     fCausesChange = FALSE;
  784.     fFileList = NULL;
  785. #if qPowerTalk
  786.     fOpenLetters = FALSE;
  787. #endif
  788. } // TFilesCommand::TFilesCommand
  789.  
  790. //----------------------------------------------------------------------------------------
  791. // TFilesCommand::Free: 
  792. //----------------------------------------------------------------------------------------
  793. #pragma segment MAClose
  794.  
  795. TFilesCommand::~TFilesCommand()
  796. {
  797.     fFileList = (TList*)FreeListIfObject(fFileList);
  798. } // TFilesCommand::Free 
  799.  
  800.  
  801. //----------------------------------------------------------------------------------------
  802. // TFilesCommand::IFilesCommand: 
  803. //----------------------------------------------------------------------------------------
  804. #pragma segment MASelCommand
  805.  
  806. void TFilesCommand::IFilesCommand(CommandNumber itsCommandNumber,
  807.                                   TList* theDocuments)
  808. {
  809.     this->IServerCommand(itsCommandNumber, gApplication, kCantUndo, kDoesNotCauseChange, NULL);
  810.     fFileList = theDocuments;
  811. } // TFilesCommand::IFilesCommand 
  812.  
  813. //----------------------------------------------------------------------------------------
  814. // TFilesCommand::IFilesCommand: 
  815. //----------------------------------------------------------------------------------------
  816. #pragma segment MASelCommand
  817.  
  818. void TFilesCommand::IFilesCommand(CommandNumber itsCommandNumber,
  819.                                   const AppleEvent& itsMessage,
  820.                                   const AppleEvent& itsReply)    // override 
  821. {
  822.     IServerCommand(itsCommandNumber, gApplication, kCantUndo, kDoesNotCauseChange, NULL,
  823.                    itsMessage, itsReply);
  824.  
  825.     // Check to see what is in the direct object list
  826.     this->GetFilesList();
  827. } // TFilesCommand::IFilesCommand 
  828.  
  829. //----------------------------------------------------------------------------------------
  830. // TFilesCommand::GetFilesList: 
  831. //----------------------------------------------------------------------------------------
  832. #pragma segment MASelCommand
  833.  
  834. void TFilesCommand::GetFilesList()
  835. {
  836.     // Check to see what is in the direct object list
  837.     CAEDesc directObj;
  838.     FailOSErr(AEGetParamDesc(&fMessage->fMessage, keyDirectObject, typeAEList, directObj));
  839.     long theCount = 0;
  840.     FailOSErr(AECountItems(directObj, &theCount));
  841.     if (theCount > 0)
  842.     {
  843.         // Get the first descriptor and see what type it is
  844.         DescType theKey;
  845.         CTempDesc theDesc;
  846.         FailOSErr(AEGetNthDesc(directObj, 1, typeWildCard, &theKey, theDesc));
  847. #if qPowerTalk
  848.         // ••• should notify user that powertalk is not available
  849.         fOpenLetters = (theDesc.GetDescriptorType() == typeLetterDesc);
  850. #endif
  851.     }
  852.  
  853. #if qPowerTalk
  854.     if (fOpenLetters)
  855.     {
  856.         fIdentifier = cOpenLetter;
  857.         fLetterList = directObj;
  858.     }
  859.     else
  860. #endif
  861.     {
  862.         MAVolatileInit(THandleList*, aHandleList, NULL);
  863.         MAVolatileInit(TList*, aFileList, NULL);
  864.         
  865.         FailInfo outerFi;
  866.         Try(outerFi)
  867.         {
  868.             aHandleList = new THandleList;
  869.             aHandleList->IHandleList();
  870.     
  871.             FailInfo innerfi;
  872.             Try(innerfi)
  873.             {
  874.                 aFileList = NewList();
  875.         
  876.                 fMessage->ReadHandleList(keyDirectObject, typeAlias, aHandleList);
  877.         
  878.                 // Block is necessary for correct failure handling
  879.                 {
  880.                     CHandleIterator iter(aHandleList);
  881.         
  882.                     for (Handle item = iter.FirstHandle(); iter.More(); item = iter.NextHandle())
  883.                     {
  884.                         MAVolatileInit(TFile*, aFile, NULL);
  885.         
  886.                         aFile = gApplication->DoMakeFile(fIdentifier);
  887.     
  888.                         FailInfo onemorefi;
  889.                         Try(onemorefi)
  890.                         {
  891.                             FailOSErr(aFile->SpecifyWithAlias(AliasHandle(item)));
  892.                             aFileList->InsertLast(aFile);
  893.                             onemorefi.Success();
  894.                         }
  895.                         else
  896.                         {
  897.                             aFile = (TFile*)FreeIfObject(aFile);
  898.                             onemorefi.ReSignal();
  899.                         }
  900.                         
  901.                         aHandleList->Delete(item);        // Delete it from the list so if we fail
  902.                                                         // we don't try to free it twice
  903.                         item = DisposeIfHandle(item);
  904.                     }
  905.                 }
  906.                 innerfi.Success();
  907.             }
  908.             else                                        // Recover
  909.             {
  910.                 if (aHandleList)
  911.                     aHandleList->FreeList();
  912.                     
  913.                 if (aFileList)
  914.                     aFileList->FreeList();
  915.             
  916.                 innerfi.ReSignal();
  917.             }
  918.             outerFi.Success();
  919.         }
  920.         else
  921.         {
  922.             this->Free();
  923.             outerFi.ReSignal();
  924.         }
  925.     
  926.         aHandleList->Free();                        // It is just a list of disposed handles…
  927.     
  928.         fFileList = aFileList;
  929.         directObj.DisposeDesc();
  930.     }
  931.  
  932. } // TFilesCommand::IFilesCommand 
  933.  
  934. //========================================================================================
  935. // CLASS TODocCommand
  936. //========================================================================================
  937. #undef Inherited
  938. #define Inherited TFilesCommand
  939.  
  940. #pragma segment MASelCommand
  941. MA_DEFINE_CLASS_M1(TODocCommand, Inherited);
  942.  
  943. //----------------------------------------------------------------------------------------
  944. // TODocCommand: Empty constructor to satisfy the compiler.
  945. //----------------------------------------------------------------------------------------
  946. #pragma segment ConstructorRes
  947.  
  948. TODocCommand::TODocCommand()
  949. {
  950. } // TODocCommand::TODocCommand
  951.  
  952. //----------------------------------------------------------------------------------------
  953. // TODocCommand destructor
  954. //----------------------------------------------------------------------------------------
  955. #pragma segment MADestructorRes
  956.  
  957. TODocCommand::~TODocCommand()
  958. {
  959. }
  960.  
  961. //----------------------------------------------------------------------------------------
  962. // TODocCommand::IODocCommand: 
  963. //----------------------------------------------------------------------------------------
  964. #pragma segment MASelCommand
  965.  
  966. void TODocCommand::IODocCommand(CommandNumber itsCommandNumber,
  967.                                 TList* theDocuments)
  968. {
  969.     this->IFilesCommand(itsCommandNumber, theDocuments);
  970. } // TODocCommand::IODocCommand 
  971.  
  972. //----------------------------------------------------------------------------------------
  973. // TODocCommand::IODocCommand: 
  974. //----------------------------------------------------------------------------------------
  975. #pragma segment MASelCommand
  976.  
  977. void TODocCommand::IODocCommand(CommandNumber itsCommandNumber,
  978.                                 const AppleEvent& itsMessage,
  979.                                 const AppleEvent& itsReply)
  980. {
  981.     this->IFilesCommand(itsCommandNumber, itsMessage, itsReply);
  982. } // TODocCommand::IODocCommand 
  983.  
  984. //----------------------------------------------------------------------------------------
  985. // TODocCommand::DoIt: 
  986. //----------------------------------------------------------------------------------------
  987. #pragma segment MAOpen
  988.  
  989. void TODocCommand::DoIt()                // override 
  990. {
  991.     FailInfo fi;
  992. //    Try(fi)
  993. //    {
  994. #if qPowerTalk
  995.     if (fOpenLetters && HasAOCEToolBox())
  996.     {
  997.         if (gMailing)
  998.             gMailing->OpenOldLetters(fIdentifier, fLetterList);
  999.     }
  1000.     else
  1001. #endif
  1002.         gApplication->OpenOld(fIdentifier, fFileList);
  1003.     
  1004. //        fi.Success();
  1005. //    }
  1006. //    else
  1007. //    {
  1008. //        this->SetValidationError(fi.error);
  1009. //        fi.ReSignal();
  1010. //    }
  1011. } // TODocCommand::DoIt 
  1012.  
  1013. //----------------------------------------------------------------------------------------
  1014. // TODocCommand::MakeAppleEvent: 
  1015. //----------------------------------------------------------------------------------------
  1016. #pragma segment MACommandRes
  1017.  
  1018. TAppleEvent* TODocCommand::MakeAppleEvent()
  1019. {
  1020.     MAVolatileInit(TAppleEvent*, mayFailEvent, NULL);
  1021.     CTempDesc theList;
  1022.  
  1023.     FailInfo fi;
  1024.     Try(fi)
  1025.     {
  1026.         TAppleEvent*    theEvent = new TAppleEvent;
  1027.         theEvent->IAppleEvent(kCoreEventClass, kAEOpenDocuments, gServerAddress, kAEWaitReply);
  1028.         mayFailEvent = theEvent;
  1029.         theList.CreateList();
  1030.         {
  1031.             CObjectIterator iter(fFileList);
  1032.             for (TFile * aFile = (TFile *)iter.FirstObject(); iter.More(); aFile = (TFile *)iter.NextObject())
  1033.             {
  1034.                 AliasHandle theAlias = NULL;
  1035.                 OSErr theErr = aFile->GetAlias(theAlias);
  1036.                 if (theErr == noErr)
  1037.                 {
  1038.                     CAEDesc theAliasDesc(typeAlias, (Handle)theAlias);
  1039.                     theList.PutListItem(0, theAliasDesc);
  1040.                 }
  1041.             }
  1042.         }
  1043.         theEvent->WriteParameter(keyDirectObject, theList);
  1044.         fi.Success();
  1045.     }
  1046.     else                                // Recover
  1047.     {
  1048.         mayFailEvent = (TAppleEvent *)FreeIfObject(mayFailEvent);
  1049.         fi.ReSignal();
  1050.     }
  1051.     return mayFailEvent;
  1052. }
  1053.  
  1054. //========================================================================================
  1055. // CLASS TPDocCommand
  1056. //========================================================================================
  1057. #undef Inherited
  1058. #define Inherited TFilesCommand
  1059.  
  1060. #pragma segment MASelCommand
  1061. MA_DEFINE_CLASS_M1(TPDocCommand, Inherited);
  1062.  
  1063. //----------------------------------------------------------------------------------------
  1064. // TPDocCommand constructor
  1065. //----------------------------------------------------------------------------------------
  1066. #pragma segment MASelCommand
  1067.  
  1068. TPDocCommand::TPDocCommand()
  1069. {
  1070.     fRequiresUserInteraction = TRUE;
  1071.     fTargetPrinter.name[0] = 0;            // no target printer
  1072. } // TPDocCommand::TPDocCommand
  1073.  
  1074. //----------------------------------------------------------------------------------------
  1075. // TPDocCommand destructor
  1076. //----------------------------------------------------------------------------------------
  1077. #pragma segment MADestructorRes
  1078.  
  1079. TPDocCommand::~TPDocCommand()
  1080. {
  1081. }
  1082.  
  1083. //----------------------------------------------------------------------------------------
  1084. // TPDocCommand::IPDocCommand: 
  1085. //----------------------------------------------------------------------------------------
  1086. #pragma segment MASelCommand
  1087.  
  1088. void TPDocCommand::IPDocCommand(CommandNumber itsCommandNumber,
  1089.                                 TList* theDocuments)
  1090. {
  1091.     this->IFilesCommand(itsCommandNumber, theDocuments);
  1092. } // TPDocCommand::IPDocCommand 
  1093.  
  1094. //----------------------------------------------------------------------------------------
  1095. // TPDocCommand::IPDocCommand: 
  1096. //----------------------------------------------------------------------------------------
  1097. #pragma segment MASelCommand
  1098.  
  1099. void TPDocCommand::IPDocCommand(CommandNumber itsCommandNumber,
  1100.                                 const AppleEvent& itsMessage,
  1101.                                 const AppleEvent& itsReply)
  1102. {
  1103.     Boolean draggedToDTP = FALSE;    // this will let us support cDragPrint
  1104.  
  1105.     AEDescList dtpList;
  1106.     OSErr err = AEGetAttributeDesc(&itsMessage, keyOptionalKeywordAttr, typeAEList, &dtpList);
  1107.     if (err == noErr)
  1108.     {
  1109.         draggedToDTP = TRUE;
  1110.         
  1111.         AEKeyword theKeyword;
  1112.         DescType typeCode;
  1113.         Size actualSize;
  1114.         
  1115.         OSErr err = AEGetNthPtr(&dtpList, 1, typeFSS, &theKeyword, &typeCode, (Ptr)&fTargetPrinter, sizeof(FSSpec), &actualSize);
  1116.         AEDisposeDesc(&dtpList);
  1117.     }
  1118.  
  1119.     this->IFilesCommand(draggedToDTP ? cDragPrint : itsCommandNumber, itsMessage, itsReply);
  1120. } // TPDocCommand::IPDocCommand 
  1121.  
  1122. //----------------------------------------------------------------------------------------
  1123. // TPDocCommand::DoIt: 
  1124. //----------------------------------------------------------------------------------------
  1125. #pragma segment MAFinder
  1126.  
  1127. void TPDocCommand::DoIt()                // override 
  1128. {
  1129.     gApplication->PrintDocuments(fIdentifier, fFileList, fTargetPrinter.name[0] ? &fTargetPrinter : NULL);
  1130. } // TPDocCommand::DoIt 
  1131.  
  1132.  
  1133. //========================================================================================
  1134. // CLASS TAboutBoxCommand
  1135. //========================================================================================
  1136. #undef Inherited
  1137. #define Inherited TCommand
  1138.  
  1139. #pragma segment MASelCommand
  1140. MA_DEFINE_CLASS_M1(TAboutBoxCommand, Inherited);
  1141.  
  1142. //----------------------------------------------------------------------------------------
  1143. // TAboutBoxCommand: Empty constructor to satisfy the compiler.
  1144. //----------------------------------------------------------------------------------------
  1145. #pragma segment ConstructorRes
  1146.  
  1147. TAboutBoxCommand::TAboutBoxCommand()
  1148. {
  1149. }
  1150.  
  1151. //----------------------------------------------------------------------------------------
  1152. // TAboutBoxCommand destructor
  1153. //----------------------------------------------------------------------------------------
  1154. #pragma segment MADestructorRes
  1155.  
  1156. TAboutBoxCommand::~TAboutBoxCommand()
  1157. {
  1158. }
  1159.  
  1160. //----------------------------------------------------------------------------------------
  1161. // TAboutBoxCommand::IAboutBoxCommand: 
  1162. //----------------------------------------------------------------------------------------
  1163. #pragma segment MASelCommand
  1164.  
  1165. void TAboutBoxCommand::IAboutBoxCommand(CommandNumber itsCommandNumber)
  1166. {
  1167.     this->ICommand(itsCommandNumber, gApplication, kCantUndo, kDoesNotCauseChange, NULL);
  1168.     FailOSErr(MAInteractWithUser());
  1169. } // TAboutBoxCommand::IAboutBoxCommand 
  1170.  
  1171. //----------------------------------------------------------------------------------------
  1172. // TAboutBoxCommand::DoIt: 
  1173. //----------------------------------------------------------------------------------------
  1174. #pragma segment MAAboutApp
  1175.  
  1176. void TAboutBoxCommand::DoIt()
  1177. {
  1178.     gApplication->DoAboutBox();
  1179. } // TAboutBoxCommand::DoIt 
  1180.  
  1181.  
  1182. //========================================================================================
  1183. // CLASS TEventRetrieverCommand
  1184. //========================================================================================
  1185.  
  1186. #if qNeedsVU
  1187.  
  1188. //========================================================================================
  1189. // CLASS TVUApplication
  1190. //========================================================================================
  1191. #undef Inherited
  1192. #define Inherited TDispatcher
  1193.  
  1194. #pragma segment MAInit
  1195. MA_DEFINE_CLASS_M1(TVUApplication, Inherited);
  1196.  
  1197. //----------------------------------------------------------------------------------------
  1198. // TVUApplication constructor 
  1199. //----------------------------------------------------------------------------------------
  1200. #pragma segment MAInit
  1201.  
  1202. TVUApplication::TVUApplication()
  1203. {
  1204. } // TVUApplication::TVUApplication
  1205.  
  1206. //----------------------------------------------------------------------------------------
  1207. // TVUApplication::IVUApplication: 
  1208. //----------------------------------------------------------------------------------------
  1209. #pragma segment MAInit
  1210.  
  1211. void TVUApplication::IVUApplication(OSType itsMainFileType,
  1212.                                     OSType itsCreator)
  1213. {
  1214.     this->IDispatcher(itsMainFileType, itsCreator);
  1215.  
  1216.     FailInfo fi;
  1217.     Try(fi)
  1218.     {
  1219.         gVUAssist = new TVUAssist();
  1220.         gVUAssist->IVUAssist(gUGridViewInitialized);
  1221.         fi.Success();
  1222.     }
  1223.     else
  1224.     {
  1225. #if qDebug
  1226.         ProgramBreak("Can't initialize the virtual user assist object!");
  1227. #endif
  1228.         this->Free();
  1229.         gVUAssist = NULL;
  1230.         // we don't fail if we have no VU support
  1231.         // Don't ReSignal
  1232.     }
  1233.  
  1234. } // TVUApplication::IVUApplication
  1235.  
  1236.  
  1237. //----------------------------------------------------------------------------------------
  1238. // TVUApplication::Free: 
  1239. //----------------------------------------------------------------------------------------
  1240. #pragma segment MAClose
  1241.  
  1242. TVUApplication::~TVUApplication()
  1243. {
  1244.     gVUAssist = (TVUAssist*)FreeIfObject(gVUAssist);
  1245. } // TVUApplication::Free 
  1246.  
  1247. //----------------------------------------------------------------------------------------
  1248. // TVUApplication::AboutToLoseControl: 
  1249. //----------------------------------------------------------------------------------------
  1250. #pragma segment MAActivate
  1251.  
  1252. void TVUApplication::AboutToLoseControl(Boolean)
  1253. {
  1254.     if (gVUAssist)
  1255.         gVUAssist->SuspendMole();
  1256. } // TVUApplication::AboutToLoseControl 
  1257.  
  1258. //----------------------------------------------------------------------------------------
  1259. // TVUApplication::RegainControl: 
  1260. //----------------------------------------------------------------------------------------
  1261. #pragma segment MAApplicationRes
  1262.  
  1263. void TVUApplication::RegainControl(Boolean)
  1264. {
  1265.     if (gVUAssist)
  1266.         gVUAssist->ResumeMole();
  1267. } // TVUApplication::RegainControl 
  1268.  
  1269. #endif
  1270.  
  1271. //========================================================================================
  1272. // CLASS TApplication
  1273. //========================================================================================
  1274. #undef Inherited
  1275.  
  1276. #if qNeedsVU
  1277. #define Inherited TVUApplication
  1278. #else
  1279. #define Inherited TDispatcher
  1280. #endif
  1281.  
  1282. #pragma segment MAInit
  1283. MA_DEFINE_CLASS_M1(TApplication, Inherited);
  1284.  
  1285. //----------------------------------------------------------------------------------------
  1286. // TApplication constructor 
  1287. //----------------------------------------------------------------------------------------
  1288. #pragma segment MAInit
  1289.  
  1290. TApplication::TApplication()
  1291. {
  1292.     // This is a special case.  It needs to be available as soon as possible.
  1293.     gApplication = this;
  1294.  
  1295.     fLaunchWithNewDocument = TRUE;
  1296.  
  1297. #if qDebug
  1298.     fDebugFlagsWindow = NULL;
  1299. #endif
  1300. } // TApplication::TApplication 
  1301.  
  1302. //----------------------------------------------------------------------------------------
  1303. // TApplication destructor
  1304. //----------------------------------------------------------------------------------------
  1305. #pragma segment MADestructorRes
  1306.  
  1307. TApplication::~TApplication()
  1308. {
  1309. }
  1310.  
  1311. //----------------------------------------------------------------------------------------
  1312. // TApplication::IApplication: 
  1313. //----------------------------------------------------------------------------------------
  1314. #pragma segment MAInit
  1315.  
  1316. void TApplication::IApplication(OSType itsMainFileType,
  1317.                                 OSType itsCreator)
  1318. {
  1319. #if qNeedsVU
  1320.     this->IVUApplication(itsMainFileType, itsCreator);
  1321. #else
  1322.     this->IDispatcher(itsMainFileType, itsCreator);
  1323. #endif
  1324.  
  1325.     FailInfo fi;
  1326.     Try(fi)
  1327.     {
  1328.         // Install the default tab  behavior 
  1329.         TMultiWindowTabber * aTabber = new TMultiWindowTabber;
  1330.         aTabber->IMultiWindowTabber(TRUE);
  1331.         this->AddBehavior(aTabber);
  1332.     
  1333.         {
  1334.             // Register views so we can create them from templates
  1335. #if qDebug
  1336.             MA_REGISTER_CLASS(TDebugFlagsView);
  1337. #endif
  1338.         }
  1339.  
  1340.         fi.Success();
  1341.     }
  1342.     else
  1343.     {
  1344. #if qDebug
  1345.         ProgramBreak("Can't initialize the application object!");
  1346. #endif
  1347.         this->Free();
  1348.         gApplication = NULL;
  1349.         fi.ReSignal();
  1350.     }
  1351. } // TApplication::IApplication 
  1352.  
  1353. //----------------------------------------------------------------------------------------
  1354. // TApplication::CanOpenDocument: 
  1355. //----------------------------------------------------------------------------------------
  1356. #pragma segment MAFinder
  1357.  
  1358. // This is called only when opening/printing from the finder and from standard file;
  1359. // it simulates the filtering done by Std File.
  1360.  
  1361. Boolean TApplication::CanOpenDocument(CommandNumber itsCommandNumber,
  1362.                                       TFile* aFile)
  1363. {
  1364.     Boolean returnValue = FALSE;
  1365.     
  1366.     ProcPtr fileFilter;
  1367.     TypeListHandle typeList = NULL;
  1368.     short dlgID;
  1369.     CPoint where;
  1370.     ProcPtr dlgHook;
  1371.     ProcPtr modalFilter;
  1372.     Ptr activeList;
  1373.     ProcPtr activateProc;
  1374.     void* yourDataPtr = NULL;
  1375.  
  1376.     this->GetStandardFileParameters(itsCommandNumber, fileFilter, typeList, dlgID, where,
  1377.                                     dlgHook, modalFilter, activeList, activateProc,
  1378.                                     NULL, yourDataPtr);
  1379.  
  1380.     CStr63 fileName;
  1381.     aFile->GetName(fileName);
  1382.  
  1383.     CInfoPBRec paramBlock;
  1384.  
  1385.     short numTypes = (short)(GetHandleSize((Handle)typeList) / sizeof(ResType));
  1386.     if (numTypes == 0)
  1387.     {
  1388.         if (!fileFilter)
  1389.             returnValue = TRUE;                    // no file filter then want all types
  1390.         else if (aFile->GetCatInfo(paramBlock) == noErr)
  1391.         {
  1392.             paramBlock.hFileInfo.ioNamePtr = (StringPtr)fileName;
  1393.             // Call through the supplied filterProc
  1394.             returnValue = !((FileFilterYDProcPtr)fileFilter)(¶mBlock, NULL);
  1395.         }
  1396.         else
  1397.             returnValue = FALSE;
  1398.     }
  1399.     else
  1400.     {
  1401.         for (short i = 0; i < numTypes; ++i)
  1402.         {
  1403.             if (((long)(aFile->fFileType)) == ((long)(*typeList)[i]))
  1404.             {
  1405.                 if (!fileFilter)
  1406.                     returnValue = TRUE;
  1407.                 else if (aFile->GetCatInfo(paramBlock) == noErr)
  1408.                 {
  1409.                     paramBlock.hFileInfo.ioNamePtr = (StringPtr)fileName;
  1410.                     // Call through the supplied filterProc
  1411.                     returnValue = !((FileFilterYDProcPtr)fileFilter)(¶mBlock, NULL);
  1412.                 }
  1413.                 else
  1414.                     returnValue = FALSE;
  1415.                 break;
  1416.             }
  1417.         }
  1418.     }
  1419.  
  1420.     typeList = (TypeListHandle)DisposeIfHandle((Handle)typeList);
  1421.     return returnValue;
  1422. } // TApplication::CanOpenDocument 
  1423.  
  1424. //----------------------------------------------------------------------------------------
  1425. // TApplication::ChooseApplication: 
  1426. //----------------------------------------------------------------------------------------
  1427. #pragma segment MAOpen
  1428.  
  1429. Boolean TApplication::ChooseApplication(AEAddressDesc& theAddress)
  1430. {
  1431.     //    typedef TargetID* TargetIDPtr,
  1432.     //    ** TargetIDHdl;
  1433.  
  1434.     TargetIDHdl theTargetID;
  1435.     LocationNameRec theLoc;
  1436.     PortInfoRec thePortInfo;
  1437.     OSErr theErr;
  1438.     CStr32 theLocNBPType;
  1439.     Boolean returnValue = FALSE;
  1440.  
  1441.     theErr = PPCBrowser(gEmptyString, gEmptyString, FALSE, &theLoc, &thePortInfo, NULL, gEmptyString);
  1442.     if (theErr == noErr)
  1443.     {
  1444.         theTargetID = (TargetIDHdl) NewPermHandle(sizeof(TargetID));
  1445.  
  1446.         (*theTargetID)->location = theLoc;
  1447.         (*theTargetID)->name = thePortInfo.name;
  1448.         theAddress.descriptorType = typeTargetID;
  1449.         theAddress.dataHandle = (Handle)theTargetID;
  1450.         returnValue = TRUE;
  1451.     }
  1452.     else if (theErr != userCanceledErr)
  1453.         FailOSErr(theErr);
  1454.     return returnValue;
  1455. } // TApplication::ChooseApplication 
  1456.  
  1457. //----------------------------------------------------------------------------------------
  1458. // TApplication::ChooseDocument: 
  1459. //----------------------------------------------------------------------------------------
  1460. #pragma segment MAOpen
  1461.  
  1462. Boolean TApplication::ChooseDocument(CommandNumber itsCommandNumber,
  1463.                                      TList** aFileList)
  1464. {
  1465.     typedef SFTypeList* SFTypeListPtr;
  1466.     typedef SFTypeListPtr* SFTypeListHandle;
  1467.  
  1468.     MAVolatileInit(TFile*, aFile, NULL);
  1469.     Boolean fileChosen;
  1470.  
  1471. #if !qPowerPC && !qModelCFM
  1472.     if (HasCustomFile())
  1473.     {
  1474. #endif
  1475.         ProcPtr fileFilter;
  1476.         TypeListHandle typeList;
  1477.         short dlgID;
  1478.         CPoint where;
  1479.         ProcPtr dlgHook;
  1480.         ProcPtr modalFilter;
  1481.         Ptr activeList;
  1482.         ProcPtr activateProc;
  1483.         StandardFileReply customReply;
  1484.         void* yourDataPtr = NULL;
  1485.         
  1486.         this->GetStandardFileParameters(itsCommandNumber, fileFilter, typeList, dlgID, where,
  1487.                                         dlgHook, modalFilter, activeList, activateProc,
  1488.                                         &customReply, yourDataPtr);
  1489.     
  1490.         SFTypeListPtr pTypeList;
  1491.         short numTypes = (short)(GetHandleSize((Handle)typeList) / sizeof(ResType));
  1492.         if (numTypes == 0)
  1493.         {
  1494.             numTypes = -1;                            // Tell Std File to display all types.
  1495.             pTypeList = (SFTypeListPtr) & pTypeList;// arbitrary, as long as it points to 4 bytes of valid memory
  1496.         }
  1497.         else
  1498.         {
  1499.             LockHandleHigh((Handle)typeList);        // in case Std File does allocations 
  1500.             pTypeList = *((SFTypeListHandle)typeList);
  1501.         }
  1502.     
  1503.         // Causes TApplication::GetEvent to call CheckRsrcUsage. 
  1504.         gRsrcCheck = 0;
  1505.     
  1506.         FailInfo fi;
  1507.         Try(fi)
  1508.         {
  1509.     
  1510.             aFile = this->DoMakeFile(itsCommandNumber);
  1511.             fileChosen = FALSE;
  1512.     
  1513.             FailOSErr(MAInteractWithUser()); 
  1514.     
  1515.             if (yourDataPtr == NULL)
  1516.                 yourDataPtr = &itsCommandNumber;
  1517.             
  1518.             gClipboardMgr->AboutToLoseControl(TRUE);            // so scrap gets converted
  1519.             
  1520.             FileFilterYDUPP cgfFileFilter = NewFileFilterYDProc(fileFilter);
  1521.             DlgHookYDUPP cgfDlgHook = NewDlgHookYDProc(dlgHook);
  1522.             ModalFilterYDUPP cgfModalFilter = NewModalFilterYDProc(modalFilter);
  1523.             ActivateYDUPP cgfActivateProc = NewActivateYDProc(activateProc);
  1524.  
  1525.             CustomGetFile(cgfFileFilter, numTypes, (*pTypeList), &customReply, dlgID, where, cgfDlgHook, cgfModalFilter, (short*)activeList, cgfActivateProc, yourDataPtr);
  1526.             
  1527.             cgfFileFilter = (FileFilterYDUPP)DisposeIfRoutineDescriptor((UniversalProcPtr)cgfFileFilter);
  1528.             cgfDlgHook = (DlgHookYDUPP)DisposeIfRoutineDescriptor((UniversalProcPtr)cgfDlgHook);
  1529.             cgfModalFilter = (ModalFilterYDUPP)DisposeIfRoutineDescriptor((UniversalProcPtr)cgfModalFilter);
  1530.             cgfActivateProc = (ActivateYDUPP)DisposeIfRoutineDescriptor((UniversalProcPtr)cgfActivateProc);
  1531.             
  1532.             gClipboardMgr->RegainControl(TRUE);            // so scrap gets converted
  1533.  
  1534.             fileChosen = customReply.sfGood;
  1535.             if (fileChosen)
  1536.                 aFile->SpecifyWithStandardFileReply(customReply);
  1537.     
  1538.             fi.Success();
  1539.         }
  1540.         else // Recover
  1541.         {
  1542.             typeList = (TypeListHandle)DisposeIfHandle((Handle)typeList);
  1543.             aFile = (TFile *)FreeIfObject(aFile);
  1544.             fi.ReSignal();
  1545.         }
  1546.     
  1547.         typeList = (TypeListHandle)DisposeIfHandle((Handle)typeList);
  1548.  
  1549.  
  1550.  
  1551. #if !qPowerPC && !qModelCFM
  1552.         // the following block of code is the "else" block for the above Gestalt check - 
  1553.         // as with that check, it is only relevant if we are not built for PowerPC
  1554.     }
  1555.     else
  1556.     {
  1557.         ProcPtr fileFilter;
  1558.         TypeListHandle typeList;
  1559.         short dlgID;
  1560.         CPoint where;
  1561.         ProcPtr dlgHook;
  1562.         ProcPtr modalFilter;
  1563.         Ptr activeList;
  1564.         ProcPtr activateProc;
  1565.         SFReply reply;
  1566.         void* yourDataPtr = NULL;
  1567.         
  1568.         // We can't pass reply because it's a lowly SFReply, not a StandardFileReply
  1569.         this->GetStandardFileParameters(itsCommandNumber, fileFilter, typeList, dlgID, where,
  1570.                                         dlgHook, modalFilter, activeList, activateProc,
  1571.                                         NULL, yourDataPtr);
  1572.     
  1573.         SFTypeListPtr pTypeList;
  1574.         short numTypes = (short)(GetHandleSize((Handle)typeList) / sizeof(ResType));
  1575.         if (numTypes == 0)
  1576.         {
  1577.             numTypes = -1;                            // Tell Std File to display all types.
  1578.             pTypeList = (SFTypeListPtr) & pTypeList;// arbitrary, as long as it points to 4 bytes of valid memory
  1579.         }
  1580.         else
  1581.         {
  1582.             LockHandleHigh((Handle)typeList);        // in case Std File does allocations 
  1583.             pTypeList = *((SFTypeListHandle)typeList);
  1584.         }
  1585.     
  1586.         // Causes TApplication::GetEvent to call CheckRsrcUsage. 
  1587.         gRsrcCheck = 0;
  1588.     
  1589.         FailInfo fi;
  1590.         Try(fi)
  1591.         {
  1592.     
  1593.             aFile = this->DoMakeFile(itsCommandNumber);
  1594.             fileChosen = FALSE;
  1595.     
  1596.             FailOSErr(MAInteractWithUser()); 
  1597.     
  1598.             if (yourDataPtr == NULL)
  1599.                 yourDataPtr = &itsCommandNumber;
  1600.             
  1601.             // We will pass the address of the CallBack instead of the modalFilter to
  1602.             // SFPGetFile It will add yourDataPtr parameter before passing on to the
  1603.             // ModalFilterProc supplied by SFPutParms this lets us assume a single calling
  1604.             // convention for that function.
  1605.  
  1606.             // Don't create a CallBack when the SF callback is NULL.
  1607.             // Also, pass itsCommandNumber as a default yourDataPtr.
  1608.             
  1609.             CallBack myFileFilterCallBack;
  1610.             SetCallBack(fileFilter, (long)yourDataPtr, &myFileFilterCallBack);
  1611.             FileFilterProcPtr aFileFilterProcPtr = fileFilter ? (FileFilterProcPtr)&myFileFilterCallBack : NULL;
  1612.  
  1613.             CallBack myModalHookCallBack;
  1614.             SetCallBack(dlgHook, (long)yourDataPtr, &myModalHookCallBack);
  1615.             DlgHookProcPtr aDlgHookProcPtr = dlgHook ? (DlgHookProcPtr)&myModalHookCallBack : NULL;
  1616.     
  1617.             CallBack myModalFilterCallBack;
  1618.             SetCallBack(modalFilter, (long)yourDataPtr, &myModalFilterCallBack);
  1619.             ModalFilterProcPtr aModalFilterProcPtr = modalFilter ? (ModalFilterProcPtr)&myModalFilterCallBack : NULL;
  1620.  
  1621.             gClipboardMgr->AboutToLoseControl(TRUE);    // so scrap gets converted
  1622.  
  1623.             SFPGetFile(where, gEmptyString, aFileFilterProcPtr, numTypes, (*pTypeList), aDlgHookProcPtr, &reply, dlgID, aModalFilterProcPtr);
  1624.             
  1625.             gClipboardMgr->RegainControl(TRUE);            // so scrap gets converted
  1626.  
  1627.             fileChosen = reply.good;
  1628.             if (fileChosen)
  1629.                 FailOSErr(aFile->SpecifyWithSFReply(reply));
  1630.             
  1631.             fi.Success();
  1632.         }
  1633.         else // Recover
  1634.         {
  1635.             typeList = (TypeListHandle)DisposeIfHandle((Handle)typeList);
  1636.             aFile = (TFile *)FreeIfObject(aFile);
  1637.             fi.ReSignal();
  1638.         }
  1639.     
  1640.         typeList = (TypeListHandle)DisposeIfHandle((Handle)typeList);
  1641.  
  1642.     }
  1643. #endif
  1644.  
  1645.     if (fileChosen)
  1646.     {
  1647.         MAVolatileInit(TList**, volatileFileList, aFileList);
  1648.         
  1649.         FailInfo fi;
  1650.         Try(fi)
  1651.         {
  1652.             // Return the file(s) chosen 
  1653.             *volatileFileList = NewList();
  1654.             (*volatileFileList)->InsertLast(aFile);
  1655.             fi.Success();
  1656.         }
  1657.         else
  1658.         {
  1659.             if (*volatileFileList)
  1660.                 *volatileFileList = (TList*)FreeIfObject(*volatileFileList);
  1661.             aFile = (TFile*)FreeIfObject(aFile);
  1662.             fi.ReSignal();
  1663.         }
  1664.     }
  1665.     else                                        // user cancelled or something 
  1666.         aFile = (TFile *)(FreeIfObject(aFile));    // free the unwanted file object 
  1667.     
  1668.     return fileChosen;
  1669. } // TApplication::ChooseDocument 
  1670.  
  1671. //----------------------------------------------------------------------------------------
  1672. // TApplication::DoMakeDocument: 
  1673. //
  1674. // E X A M P L E
  1675. // {
  1676. //         TDocument*    aYOURDocument = NULL;
  1677. //
  1678. //         aYOURDocument = new TDocument;
  1679. //         aYOURDocument->IYOURDocument();
  1680. //        return aYOURDocument;
  1681. // }
  1682. //----------------------------------------------------------------------------------------
  1683. #pragma segment MANever
  1684.  
  1685. TDocument* TApplication::DoMakeDocument(CommandNumber, TFile*)
  1686. {
  1687.     this->SubClassResponsibility();
  1688.     return NULL;                                // So that CFront doesn't complain
  1689. } // TApplication::DoMakeDocument 
  1690.  
  1691. //----------------------------------------------------------------------------------------
  1692. // TApplication::DoMenuCommand: 
  1693. //----------------------------------------------------------------------------------------
  1694. #pragma segment MASelCommand
  1695.  
  1696. void TApplication::DoMenuCommand(CommandNumber aCommandNumber)
  1697. {
  1698.     // ===================================================================================
  1699.     // Some commands will be posted to perform actions that must _ALWAYS_ be available.
  1700.     // The allocation cannot be allowed to fail. So we do a temp allocation which by
  1701.     // definition cannot be allowed to fail. This strategy is used wherever we want to use
  1702.     // command objects but don't want to leave the user twisting in the breeze. NOTE:
  1703.     // Don't forget to allow for this memory in your mem! resource if you copy this style
  1704.     // in your own code.
  1705.     // ===================================================================================
  1706.  
  1707.     switch (aCommandNumber)
  1708.     {
  1709.         case cQuit:
  1710.             {
  1711.                 Boolean oldTempAlloc = TemporaryAllocation(TRUE);
  1712.                 Boolean oldObjectPerm = AllocateObjectsFromPerm(FALSE);
  1713.                 TQuitCommand * aQuitCommand;
  1714.                 aQuitCommand = new TQuitCommand;
  1715.                 aQuitCommand->IQuitCommand(aCommandNumber);
  1716.                 this->PostCommand(aQuitCommand);
  1717.                 TemporaryAllocation(oldTempAlloc);
  1718.                 AllocateObjectsFromPerm(oldObjectPerm);
  1719.             }
  1720.             break;
  1721.  
  1722.         case cNew:                                // cNew..cNewLast:
  1723.         case 11:
  1724.         case 12:
  1725.         case 13:
  1726.         case 14:
  1727.         case 15:
  1728.         case 16:
  1729.         case 17:
  1730.         case 18:
  1731.         case cNewLast:
  1732.         case cFinderNew:
  1733.             this->DoNew(aCommandNumber);
  1734.             break;
  1735.  
  1736.         case cOpen:                                // cOpen..cOpenLast:
  1737.         case 21:
  1738.         case 22:
  1739.         case 23:
  1740.         case 24:
  1741.         case 25:
  1742.         case 26:
  1743.         case 27:
  1744.         case 28:
  1745.         case cOpenLast:
  1746.             this->DoOpen(aCommandNumber);
  1747.             break;
  1748.  
  1749.         case cAboutApp:
  1750.             {
  1751.                 TAboutBoxCommand * aAboutAppCommand = new TAboutBoxCommand;
  1752.                 aAboutAppCommand->IAboutBoxCommand(aCommandNumber);
  1753.                 this->PostCommand(aAboutAppCommand);
  1754.             }
  1755.             break;
  1756.  
  1757. #if qDebug
  1758.         case cDebugFlags:
  1759.             {
  1760.                 if (!fDebugFlagsWindow)
  1761.                     FailNIL(fDebugFlagsWindow = gViewServer->NewTemplateWindow(kDebugFlagsView, NULL));
  1762.                 fDebugFlagsWindow->Open();
  1763.                 fDebugFlagsWindow->Select();
  1764.             }
  1765.             break;
  1766.  
  1767.         case cRefreshFrontWindow:
  1768.             {
  1769.                 TWindow * aWindow = this->GetActiveWindow(kNoFloaters);
  1770.  
  1771.                 if (aWindow)
  1772.                     aWindow->ForceRedraw();
  1773.             }
  1774.             break;
  1775.  
  1776.         case cDoFirstClick:
  1777.             {
  1778.                 TWindow * aWindow = this->GetActiveWindow(kNoFloaters);
  1779.  
  1780.                 if (aWindow)
  1781.                     aWindow->fDoFirstClick = !aWindow->fDoFirstClick;
  1782.             }
  1783.             break;
  1784.  
  1785.         // System Justification - see comment in Debug.r
  1786.     //    case cSetSysJust:
  1787.             // swap the current setting 
  1788.     //        if (GetSysDirection() == smSysJustLeft)
  1789.     //            SetSysDirection(smSysJustRight);
  1790.     //        else
  1791.     //            SetSysDirection(smSysJustLeft);
  1792.     //        break;
  1793. #endif
  1794.  
  1795. #if qPerform
  1796.         case cPerfMonInit:
  1797.             {
  1798.                 TWindow* aWindow;
  1799.                 IDType dismisser;
  1800.                 
  1801.                 FailNIL(aWindow = gViewServer->NewTemplateWindow(kPerfMonInitView, NULL));
  1802.                 dismisser = aWindow->PoseModally();
  1803.                 if (dismisser == 'init')
  1804.                     InitiatePerfMonitor(aWindow);
  1805.                 aWindow->CloseAndFree();
  1806.             }
  1807.             break;
  1808.             
  1809.         case cPerfMonDump:
  1810.             {
  1811.                 StandardFileReply replyRec;
  1812.                 StandardPutFile((StringPtr)"\pSave as:", (StringPtr)"\puntitled", &replyRec);
  1813.                 if (replyRec.sfGood)
  1814.                     DumpPerfMonitor(replyRec.sfFile);
  1815.             }
  1816.             break;                
  1817.             
  1818.         case cPerfMonToggle:
  1819.             EnablePerfMonitor(!PerfMonitorEnabled());
  1820.             break;
  1821.             
  1822.         case cPerfMonEnd:
  1823.             TerminatePerfMonitor();
  1824.             break;
  1825. #endif
  1826.             
  1827.         default:
  1828.             Inherited::DoMenuCommand(aCommandNumber);
  1829.             break;
  1830.     }
  1831. } // TApplication::DoMenuCommand 
  1832.  
  1833. //----------------------------------------------------------------------------------------
  1834. // TApplication::DoSetupMenus: 
  1835. //----------------------------------------------------------------------------------------
  1836. #pragma segment MAApplicationRes
  1837.  
  1838. void TApplication::DoSetupMenus()
  1839. {
  1840.     Inherited::DoSetupMenus();
  1841.  
  1842.     Boolean lowSpace = MemSpaceIsLow();
  1843.  
  1844.     Enable(cAboutApp, TRUE);
  1845.     Enable(-(mApple << 8), TRUE);    // allow the whole menu
  1846.  
  1847.     Enable(cQuit, fEventLevel <= 1);    // Can't enable Quit if in nested event handling
  1848.     Enable(cNew, !lowSpace);
  1849.     Enable(cOpen, !lowSpace);
  1850.  
  1851. #if qDebug
  1852.     {
  1853.         TWindow* aWindow = gApplication->GetActiveWindow(kNoFloaters);
  1854.  
  1855.         Enable(cRefreshFrontWindow, (aWindow != NULL));
  1856.         Enable(cDoFirstClick, (aWindow != NULL));
  1857.         if (aWindow)
  1858.             SetMenuState(cDoFirstClick, kDebugBuzzStrings, bzDoFirstClick, bzDontDoFirstClick, aWindow->fDoFirstClick);
  1859.  
  1860.         Enable(cDebugFlags, TRUE);
  1861.  
  1862.         // System Justification - see comment in Debug.r
  1863.         //    Enable(cSetSysJust, TRUE);
  1864.         //    SetMenuState(cSetSysJust, kDebugBuzzStrings, bzSetRightSysJust, bzSetLeftSysJust, GetSysDirection() != smSysJustLeft);
  1865.     }
  1866. #endif
  1867.  
  1868. #if qPerform
  1869.     {
  1870.         Boolean initiated = PerfMonitorInitiated();
  1871.         
  1872.         Enable(cPerfMonInit, !initiated);
  1873.         Enable(cPerfMonDump, initiated);
  1874.         Enable(cPerfMonToggle, initiated);
  1875.         SetMenuState(cPerfMonToggle, kDebugBuzzStrings, bzContinuePerfMon, bzPausePerfMon, PerfMonitorEnabled());
  1876.         Enable(cPerfMonEnd, initiated);
  1877.     }
  1878. #endif
  1879.  
  1880. } // TApplication::DoSetupMenus 
  1881.  
  1882. //----------------------------------------------------------------------------------------
  1883. // TApplication::DoAboutBox: Method to display the "About" box for your application.
  1884. // Override to do interesting things. Since it is normally called from a command; the app
  1885. // usually has the maximum free space available.
  1886. //----------------------------------------------------------------------------------------
  1887. #pragma segment MAAboutApp
  1888.  
  1889. void TApplication::DoAboutBox()
  1890. {
  1891.     FailSpaceIsLow();
  1892.     FailOSErr(MAInteractWithUser());
  1893.  
  1894.     CStr255 apName;
  1895.     this->GetApplicationName(apName);
  1896.  
  1897.     ParamText(apName, gEmptyString, gEmptyString, gEmptyString);                // Put Application name in the about box 
  1898.  
  1899.     if (GetResource('STR#', kDefaultCredits))
  1900.     {
  1901.         lastCreditsStringIndex = 1;
  1902.         lastCreditsShownTicks = TickCount();
  1903.         waitTicks = 5 * 60;
  1904.         originalText = (CStringHandle)NewString(gEmptyString);
  1905.         FailNIL(originalText);
  1906.         MacAppAlert(phAboutApp, (ProcPtr)DoShowAboutAppFilter);
  1907.         originalText = (CStringHandle)DisposeIfHandle((Handle)originalText);
  1908.     }
  1909.     else
  1910.         StdAlert(phAboutApp);
  1911. } // TApplication::DoAboutBox 
  1912.  
  1913. //----------------------------------------------------------------------------------------
  1914. // TApplication::HandleFinderRequest: 
  1915. //----------------------------------------------------------------------------------------
  1916. #pragma segment MAFinder
  1917.  
  1918. void TApplication::HandleFinderRequest()
  1919. {
  1920. } // TApplication::HandleFinderRequest 
  1921.  
  1922. //----------------------------------------------------------------------------------------
  1923. // TApplication::KindOfDocument: 
  1924. //----------------------------------------------------------------------------------------
  1925. #pragma segment MAOpen
  1926.  
  1927. CommandNumber TApplication::KindOfDocument(CommandNumber itsCommandNumber,
  1928.                                                   TFile*)
  1929. {
  1930.     return itsCommandNumber;
  1931. } // TApplication::KindOfDocument 
  1932.  
  1933. //----------------------------------------------------------------------------------------
  1934. // TApplication::OpenNew: 
  1935. //----------------------------------------------------------------------------------------
  1936. #pragma segment MAOpen
  1937.  
  1938. TDocument* TApplication::OpenNew(CommandNumber itsCommandNumber)
  1939. {
  1940.     MAVolatileInit(TDocument*, aDocument, NULL);
  1941.  
  1942.     FailInfo fi;
  1943.     Try(fi)
  1944.     {
  1945.         FailNIL(aDocument = this->DoMakeDocument(this->KindOfDocument(itsCommandNumber, NULL), NULL));
  1946.         aDocument->DoInitialState();
  1947.  
  1948.         aDocument->DoMakeViews(kForDisplay);
  1949.  
  1950.         CStr255 newTitle;
  1951.         aDocument->UntitledName(newTitle);
  1952.         aDocument->SetTitle(newTitle);
  1953.  
  1954.         FailSpaceIsLow();                        // Fail if document leaves us with no room 
  1955.  
  1956.         // Don't attempt to show the windows until we're sure we won't fail 
  1957.         aDocument->DoPostMakeViews(kForDisplay);
  1958.  
  1959.         fi.Success();
  1960.     }
  1961.     else // Recover
  1962.     {
  1963.         if (aDocument)
  1964.             aDocument = (TDocument *)(FreeIfObject(aDocument));    // The document will free the file
  1965.  
  1966.         FailNewMessage(fi.error, fi.message, messageNewFailed);
  1967.     }
  1968.     return aDocument;
  1969. } // TApplication::OpenNew 
  1970.  
  1971. //----------------------------------------------------------------------------------------
  1972. // TApplication::OpenOld: 
  1973. //----------------------------------------------------------------------------------------
  1974. #pragma segment MAOpen
  1975.  
  1976. TDocument* TApplication::OpenOld(CommandNumber itsOpenCommand, TList* aFileList)
  1977. {
  1978.     MAVolatileInit(TDocument*, aDocument, NULL);
  1979.     MAVolatileInit(TFile*, aFile, NULL);
  1980.     MAVolatileInit(TFile*, aNewFile, NULL);
  1981.     MAVolatileInit(OSErr, savedError, 0);
  1982.     MAVolatileInit(long, savedMessage, 0);
  1983.     
  1984.     Size oldCodeReserve;    // can't be volatile because it is passed by reference
  1985.     Size oldMemReserve;        // can't be volatile because it is passed by reference
  1986.  
  1987.     {
  1988.         // Put iterator in a separate block so that it will go out of scope before the end of the method.
  1989.         // We don't want the iterator's failure handler to be invoked, because its stack ptr is munged.
  1990.         // If an error occurs, we'll just save it and ReSignal it after the iterator is gone.
  1991.         
  1992.         CObjectIterator iter(aFileList);
  1993.         for (aFile = (TFile *)iter.FirstObject(); iter.More() && !savedError; aFile = (TFile *)iter.NextObject())
  1994.         {
  1995.             CommandNumber kindOfDocCmd = this->KindOfDocument(itsOpenCommand, aFile);
  1996.             // reset aDocument and aNewFile so that they no longer refer to items from the
  1997.             // last go round (important in case we fail downstream)…
  1998.             aDocument = NULL;
  1999.             aNewFile = NULL;
  2000.             
  2001.             CStr63 fileName;
  2002.             aFile->GetName(fileName);            // If failure occurs the file may already be
  2003.                                                 // freed so we will save the name just in
  2004.                                                 // case.
  2005.             
  2006.             aFileList->Delete(aFile);            // ReadStationery if successful will dispose
  2007.                                                 // of the file for us so if failure occurs
  2008.                                                 // this had better not be in the file list.
  2009.             
  2010.             FailInfo fi;
  2011.             Try(fi)
  2012.             {
  2013.                 // Set reserve down a little to ensure that we can open existing documents 
  2014.                 GetReserveSize(oldCodeReserve, oldMemReserve);
  2015.                 SetReserveSize(oldCodeReserve, oldMemReserve / 2);
  2016.                 
  2017.                 TDocument * otherDoc = this->FindDocument(aFile);
  2018.                 Boolean isStationery = aFile->IsStationery();
  2019.                 
  2020.                 if (otherDoc && !isStationery)
  2021.                 {
  2022.                     otherDoc->OpenAgain(kindOfDocCmd, aDocument);
  2023.                     aFile = (TFile*)FreeIfObject(aFile);
  2024.                     SetReserveSize(oldCodeReserve, oldMemReserve);
  2025.                 }
  2026.                 else if (this->CanOpenDocument(kindOfDocCmd, aFile))
  2027.                 {
  2028.                     TFile* fileOwnedByDoc = aFile;
  2029.                     aFile = NULL;
  2030.                     FailNIL(aDocument = this->DoMakeDocument(kindOfDocCmd, fileOwnedByDoc));
  2031.  
  2032.                     if (!isStationery)
  2033.                         aDocument->ReadDocument(kForDisplay);
  2034.                     else
  2035.                     {
  2036.                         aNewFile = this->DoMakeFile(kindOfDocCmd);
  2037.                         aDocument->ReadStationery(aNewFile);
  2038.                         aFile = NULL;                // This file has already been freed by ReadStationery.
  2039.                         aNewFile = NULL;            // Clear our reference so that if we fail
  2040.                                                     // we don't try to free this file twice.
  2041.                     }
  2042.                     
  2043.                     aDocument->DoMakeViews(kForDisplay);
  2044.     
  2045.                     if (isStationery)
  2046.                     {
  2047.                         CStr255 newTitle;
  2048.                         aDocument->UntitledName(newTitle);
  2049.                         aDocument->SetTitle(newTitle);
  2050.                     }
  2051.         
  2052.                     FailSpaceIsLow();                // Fail if the document leaves us with no
  2053.                                                     // memory
  2054.                     // Set the reserve back to where it was 
  2055.                     SetReserveSize(oldCodeReserve, oldMemReserve);
  2056.         
  2057.                     // Don't attempt to show the windows until we're sure we won't fail 
  2058.                     aDocument->DoPostMakeViews(kForDisplay);
  2059.                 }
  2060.                 else
  2061.                     Failure(errNotMyType, 0);
  2062.                 fi.Success();
  2063.             }
  2064.             else // Recover
  2065.             {
  2066.                 if (fi.message == 0)
  2067.                     gErrorParm3 = fileName;
  2068.                     
  2069.                 // We may have ended up without a document because of a failure during document
  2070.                 // init. b/c this can be the case we don't know what happened to aFile, whether 
  2071.                 // it was freed by the document in the failure process or orphaned. Because of
  2072.                 // this we will not free aFile here.
  2073.                 if (aDocument)
  2074.                     aDocument = (TDocument *)(FreeIfObject(aDocument));    // The document will free the file
  2075.                     
  2076.                 aNewFile = (TFile*)FreeIfObject(aNewFile);                // If we successfully read the
  2077.                                                                         // stationery then aNewFile will be NULL
  2078.                 
  2079.                 // Set the reserve back to where it was 
  2080.                 SetReserveSize(oldCodeReserve, oldMemReserve);
  2081.                 
  2082.                 //    Don't want to fail here, because the CObjectIterator (with its embedded FailInfo) is 
  2083.                 //    still in scope. Instead, save the error info until after the iterator has self-destructed.
  2084.                 //    FailNewMessage(fi.error, fi.message, messageOpenFailed);
  2085.                 savedError = fi.error;
  2086.                 savedMessage = fi.message;
  2087.                 if (!savedMessage)
  2088.                     savedMessage = messageOpenFailed;
  2089.             }
  2090.         }
  2091.     } // iterator will self-destruct now
  2092.  
  2093.       if (savedError != noErr)                        // Do we need to ReSignal a failure?
  2094.     {
  2095.         // signal the failure
  2096.         Failure(savedError, savedMessage);
  2097.     }
  2098.     return aDocument;
  2099. } // TApplication::OpenOld 
  2100.  
  2101. //----------------------------------------------------------------------------------------
  2102. // TApplication::PrintDocuments: 
  2103. //----------------------------------------------------------------------------------------
  2104. #pragma segment MAFinder
  2105.  
  2106. void TApplication::PrintDocuments(CommandNumber itsCommandNumber, TList* aFileList, const FSSpec* targetPrinter)
  2107. {
  2108.     MAVolatileInit(TDocument*, aDocument, NULL);
  2109.     MAVolatileInit(TFile*, aFile, NULL);
  2110.  
  2111.     TPrintHandler::gFinderPrintingProceed = TRUE;            // set in TStdPrintHandler::DoPrintCommand
  2112.     TPrintHandler::gPrintHandler->PrepareForFinderPrinting(targetPrinter);
  2113.  
  2114.     CObjectIterator iter(aFileList);
  2115.     for (aFile = (TFile *)iter.FirstObject(); iter.More(); aFile = (TFile *)iter.NextObject())
  2116.     {
  2117.         if (TPrintHandler::gFinderPrintingProceed)
  2118.         {
  2119.             FailInfo fi;
  2120.             Try(fi)
  2121.             {
  2122.                 FailNIL(aDocument = this->DoMakeDocument(this->KindOfDocument(itsCommandNumber, aFile), aFile));
  2123.                 aDocument->ReadDocument(kForPrinting);
  2124.                 aDocument->DoMakeViews(kForPrinting);
  2125.                 aDocument->DoPostMakeViews(kForPrinting);
  2126.  
  2127.                 aDocument->HandleMenuCommand(itsCommandNumber);
  2128.  
  2129.                 fi.Success();
  2130.             }
  2131.             else // Recover
  2132.             {
  2133.                 if (aDocument)
  2134.                 {
  2135.                     // If there is a document then it will have a reference to aFile and
  2136.                     // will free it when it is freed. Therefore we need to remove it from
  2137.                     // the list so that when the file list is freed we don't attempt to
  2138.                     // free it twice.
  2139.                     aFileList->Delete(aFile);
  2140.                     aDocument = (TDocument *)FreeIfObject(aDocument);
  2141.                 }
  2142.                 fi.ReSignal();
  2143.             }
  2144.             aFileList->Delete(aFile);
  2145.             aDocument = (TDocument *)FreeIfObject(aDocument);
  2146.         }
  2147.         else
  2148.             break;                                // The user canceled printing
  2149.     }
  2150. } // TApplication::PrintDocuments 
  2151.  
  2152. //----------------------------------------------------------------------------------------
  2153. // TApplication::GetStandardFileParameters: 
  2154. //----------------------------------------------------------------------------------------
  2155. #pragma segment MAOpen
  2156.  
  2157. void TApplication::GetStandardFileParameters(CommandNumber itsCommandNumber,
  2158.                                              ProcPtr& fileFilter,
  2159.                                              TypeListHandle& typeList,
  2160.                                              short& dlgID,
  2161.                                              CPoint& where,
  2162.                                              ProcPtr& dlgHook,
  2163.                                              ProcPtr& modalFilter,
  2164.                                              Ptr& activeList,
  2165.                                              ProcPtr& activateProc,
  2166.                                              StandardFileReply* /*reply*/,
  2167.                                              void*& yourDataPtr)
  2168. {
  2169.     dlgID = sfGetDialogID;
  2170.     where = kBestSystemLocation;
  2171.  
  2172.     this->GetFileTypeList(itsCommandNumber, typeList);
  2173.  
  2174.     fileFilter = NULL;
  2175.     dlgHook = NULL;
  2176.     modalFilter = (ProcPtr)gModalFilterYDProcPtr;
  2177.     activeList = NULL;
  2178.     activateProc = NULL;
  2179.     yourDataPtr = NULL;
  2180. } // TApplication::GetStandardFileParameters 
  2181.  
  2182. //----------------------------------------------------------------------------------------
  2183. // TApplication::GetFileTypeList: 
  2184. //----------------------------------------------------------------------------------------
  2185. #pragma segment MAOpen
  2186.  
  2187. void TApplication::GetFileTypeList(CommandNumber,
  2188.                                    TypeListHandle& typeList)
  2189. {
  2190.     typeList = (TypeListHandle) NewPermHandle(4);
  2191.     (*typeList)[0] = fMainFileType;
  2192. } // TApplication::GetFileTypeList 
  2193.  
  2194. //----------------------------------------------------------------------------------------
  2195. // TApplication::DoNew: 
  2196. //----------------------------------------------------------------------------------------
  2197. #pragma segment MAScriptingRes
  2198.  
  2199. void TApplication::DoNew(CommandNumber theCmdNumber)
  2200. {
  2201.     TNewDocumentCommand *aNewDocCommand = new TNewDocumentCommand;
  2202.     aNewDocCommand->INewDocumentCommand(theCmdNumber);
  2203.     aNewDocCommand->fUseAppleEvent = TRUE;
  2204.     this->PostCommand(aNewDocCommand);
  2205. }
  2206.  
  2207. //----------------------------------------------------------------------------------------
  2208. // TApplication::DoOpen: 
  2209. //----------------------------------------------------------------------------------------
  2210. #pragma segment MAScriptingRes
  2211.  
  2212. void TApplication::DoOpen(CommandNumber theCmdNumber)
  2213. {
  2214.     TList* aFileList = NULL;    // passed by address
  2215.  
  2216.     if (this->ChooseDocument(theCmdNumber, &aFileList))
  2217.     {
  2218.         TODocCommand * anODocCommand = new TODocCommand;
  2219.         anODocCommand->IODocCommand(theCmdNumber, aFileList);
  2220.         anODocCommand->fUseAppleEvent = TRUE;
  2221.         this->PostCommand(anODocCommand);
  2222.     }
  2223. }
  2224.  
  2225. //----------------------------------------------------------------------------------------
  2226. // TApplication::DoAECreateElement: 
  2227. //----------------------------------------------------------------------------------------
  2228. #pragma segment MAScriptingRes
  2229.  
  2230. void TApplication::DoAECreateElement(TAppleEvent* message,
  2231.                                      TAppleEvent* reply)
  2232. {
  2233.     // Creates a new document. If your application has more than one type of document
  2234.     // you'll need to override this method. The default simulates choosing "New" from
  2235.     // the file menu.
  2236.     DescType theClass = message->ReadType(keyAEObjectClass);
  2237.     if (IsDocumentClass(theClass) || (theClass == cWindow))
  2238.     {
  2239.         if (CommandEnabled(cNew))
  2240.         {
  2241.             TDocument * theDoc = this->OpenNew(cNew);
  2242.             // Apply the properties if any.
  2243.             theDoc->SetPropertiesFromEvent(message);
  2244.             
  2245.             // Apply the initial data if any
  2246.             if (message->HasParameter(keyAEData))
  2247.                 theDoc->DoAESetData(message, reply);
  2248.  
  2249.             // Return the document's object specifier
  2250.             CTempDesc theDocsSpecifier;
  2251.             theDoc->MakeObjectSpecifier(theDocsSpecifier, formName);
  2252.             if (reply->fMessage.dataHandle)
  2253.                 reply->WriteParameter(keyAEResult, theDocsSpecifier);
  2254.         }
  2255.     }
  2256. }
  2257.  
  2258. //----------------------------------------------------------------------------------------
  2259. // TApplication::DoAEClose: 
  2260. //----------------------------------------------------------------------------------------
  2261. #pragma segment MAScriptingRes
  2262.  
  2263. void TApplication::DoAEClose(TAppleEvent* message,
  2264.                              TAppleEvent* reply)
  2265. {
  2266.     if (CommandEnabled(cQuit))
  2267.     {
  2268.         Boolean oldTempAlloc = TemporaryAllocation(TRUE);
  2269.         Boolean oldObjectPerm = AllocateObjectsFromPerm(FALSE);
  2270.         TQuitCommand* quitCommand = NULL;
  2271.         Boolean quitIsBeingProcessed = TRUE;
  2272.  
  2273.         quitCommand = new TQuitCommand;
  2274.         quitCommand->IQuitCommand(message, reply, &quitIsBeingProcessed);
  2275.  
  2276.         quitCommand->Process();
  2277.  
  2278.         TemporaryAllocation(oldTempAlloc);
  2279.         AllocateObjectsFromPerm(oldObjectPerm);
  2280.     }
  2281. }
  2282.  
  2283. //----------------------------------------------------------------------------------------
  2284. // TApplication::DoScriptCommand: 
  2285. //----------------------------------------------------------------------------------------
  2286. #pragma segment MAScriptingRes
  2287.  
  2288. void TApplication::DoScriptCommand(CommandNumber    aCommandNumber,
  2289.                                     TAppleEvent*     message,
  2290.                                        TAppleEvent*     reply)
  2291. {
  2292.     TEventHandler * theTarget = this->GetTarget();
  2293.  
  2294.     switch (aCommandNumber)
  2295.     {
  2296.         case cFinderNew:
  2297.             // Special case the old MacPaint style open if user knows about the option
  2298.             // key. Only if the application is frontmost though.
  2299.             if (this->IsFrontProcess() && IsOptionKeyDown())
  2300.                 this->HandleMenuCommand(cOpen);
  2301.             else if (fLaunchWithNewDocument)
  2302.                 this->GetTarget()->HandleMenuCommand(cFinderNew);
  2303.             break;
  2304.  
  2305.         case cFinderOpen:
  2306.             {
  2307.                 TODocCommand * anODocCommand = new TODocCommand;
  2308.                 anODocCommand->IODocCommand(aCommandNumber, message->fMessage, reply->fMessage);
  2309.                 this->PostCommand(anODocCommand);
  2310.             }
  2311.             break;
  2312.  
  2313.         case cFinderPrint:
  2314.         case cDragPrint:
  2315.             {
  2316.                 TPDocCommand * aPDocCommand = new TPDocCommand;
  2317.                 aPDocCommand->IPDocCommand(aCommandNumber, message->fMessage, reply->fMessage);
  2318.                 this->PostCommand(aPDocCommand);
  2319.             }
  2320.             break;
  2321.             
  2322.         case cSectionRead:
  2323.         case cSectionWrite:
  2324.         case cSectionScroll:
  2325.         case cSectionCancel:
  2326.             {
  2327.                 TSectionMgr* aSectionMgr = (TSectionMgr*) this->GetBehaviorWithIdentifier(kSectionMgrBehaviorID);
  2328.                 aSectionMgr->DoAESectionEvent(aCommandNumber, message->fMessage, reply->fMessage);
  2329.             }
  2330.             break;
  2331.  
  2332.         default:
  2333.             //MDefaultScriptableObject::DoScriptCommand(aCommandNumber, message, reply);
  2334.             Inherited::DoScriptCommand(aCommandNumber, message, reply);
  2335.             break;
  2336.     }
  2337. }
  2338.  
  2339. //----------------------------------------------------------------------------------------
  2340. // End of UApplication.cp 
  2341.  
  2342. #pragma segment Inline
  2343.